#include <iostream>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>

using namespace std;

// int main()
// {
//     while (1)
//     {
//         cout << "hello world" << endl;
//         sleep(1); // 暂停1秒
//     }
//     return 0;
// }

// int main()
// {
//     cout << "I am running in the main process" << endl;
//     sleep(1); // 暂停1秒
//     int a = 1 / 0;
//     return 0;
// }

// int main()
// {
//     // 创建一个子进程
//     pid_t pid = fork();
//     if (pid < 0)
//     {
//         // fork 失败
//         perror("fork failed");
//         return EXIT_FAILURE;
//     }

//     if (pid == 0)
//     {
//         // -------------------
//         // 子进程执行部分
//         // -------------------
//         printf("I am running...\n");

//         // 故意制造野指针写操作，触发段错误 (SIGSEGV)
//         int *p = NULL;
//         *p = 100; // 这里会导致子进程收到 SIGSEGV 并生成 core dump

//         // 不应该执行到这里
//         exit(0);
//     }

//     // -------------------
//     // 父进程执行部分
//     // -------------------
//     int status = 0;
//     // 等待子进程结束，并获取退出状态
//     waitpid(pid, &status, 0);

//     // 从 status 中提取相关信息：
//     // - 退出码：存放在高 8 位 ((status >> 8) & 0xff)
//     // - core dump 标志：低字节第 7 位 ((status >> 7) & 1)
//     // - 终止信号：低 7 位 (status & 0x7f)
//     int exitCode = (status >> 8) & 0xff;
//     int coreDumped = (status >> 7) & 1;
//     int termSignal = status & 0x7f;

//     // 打印结果
//     printf("exitCode: %d, coreDump: %d, signal: %d\n",
//            exitCode, coreDumped, termSignal);

//     return 0;
// }

// void handler(int signal)
// {
//     printf("get a signal:%d\n", signal);
// }
// int main()
// {
//     int signo;
//     for (signo = 1; signo <= 31; signo++)
//     {
//         signal(signo, handler);
//     }
//     while (1)
//     {
//         sleep(1);
//     }
//     return 0;
// }

// 孤儿进程了
// int main()
// {
//     pid_t pid = fork();
//     if (pid == 0)
//     {
//         while (1)
//         {
//             cout << "I am a process.. pid:" << getpid() << endl;
//             sleep(1);
//         }
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <stdlib.h>
// int main()
// {
//     pid_t pid = getpid();
//     while (1)
//     {
//         printf("I am a process...pid:%d\n", pid);
//         sleep(1); // 每秒打印一次，避免打印过快
//     }
//     return 0;
// }

// #include <stdio.h>
// #include <unistd.h>
// #include <signal.h>

// void handler(int signal)
// {
//     cout << "get a signal:" << signal << endl;
// }
// int main()
// {
//     signal(2, handler);
//     // 或者signal(SIGINT, handler);
//     while (1)
//     {
//         sleep(1);
//         raise(2); // 发送信号2 (SIGINT)
//     }
//     return 0;
// }

// 多I/O
//  int main()
//  {
//      int count = 0;
//      alarm(1); // 设置定时器，1秒后发送
//      while (1)
//      {
//          cout << "count:" << count << endl;
//          count++;
//      }
//      return 0;
//  }

// 多 I/O：每次都写屏幕 → 系统调用、缓冲刷新 → 速度慢。

// 少 I/O：只在结束时写一次 → 循环内无 I/O → 速度快数千倍。

// int count = 0;
// void handler(int sig)
// {
//     cout << "count:" << count << std::endl;
//     exit(0);
// }
// int main()
// {
//     signal(SIGALRM, handler);
//     alarm(1);
//     while (true)
//     {
//         count++;
//     }
//     return 0;
// }

// SIGPIPE信号实际上就是一种由软件条件产生的信号，当进程在使用管道进行通信时，读端进程将读端关闭，而写端进程还在一直向管道写入数据，那么此时写端进程就会收到SIGPIPE信号进而被操作系统终止。

// int main()
// {
//     int fd[2];
//     if (pipe(fd) < 0) // 创建管道
//     {
//         perror("pipe");
//         return 1;
//     }
//     pid_t pid = fork();
//     if (pid == 0)
//     {
//         close(fd[0]); // 关闭读端
//         const char *msg = "hello father,I am son..";
//         int count = 10;
//         while (count--)
//         {
//             write(fd[1], msg, strlen(msg));
//             sleep(1);
//         }
//         close(fd[1]); // 关闭写端
//         exit(0);
//     }
//     close(fd[1]);
//     close(fd[0]);
//     int status = 0;
//     waitpid(pid, &status, 0);
//     status = status & 0x7f;
//     cout << "child get signal:" << status << endl;
//     return 0;
// }

void childSignalHandler(int sig)
{
    int status;
    pid_t pid;
    while (pid = waitpid(-1, &status, WNOHANG))
    {
        cout << "父进程：回收了子进程" << pid << endl;
        if (WIFEXITED(status))
        {
            cout << "子进程" << pid << "正常退出，退出码：" << WEXITSTATUS(status) << endl;
        }
        else if (WIFSIGNALED(status))
        {
            cout << "子进程" << pid << "异常退出，信号：" << WTERMSIG(status) << endl;
        }
        else if (WIFSTOPPED(status))
        {
            cout << "子进程" << pid << "停止，信号：" << WSTOPSIG(status) << endl;
        }
    }
}
int main()
{
    if (signal(SIGCHLD, childSignalHandler) == SIG_ERR)
    {
        perror("signal");
        return 1;
    }
    cout << "父进程：PID 为 " << getpid() << endl;

    // 创建一个子进程
    pid_t pid = fork();

    if (pid < 0)
    {
        // fork 失败
        perror("fork");
        return 1;
    }
    else if (pid == 0)
    {
        // 子进程代码
        cout << "子进程：PID 为 " << getpid() << "，父进程 PID 为 " << getppid() << endl;
        cout << "子进程：正在工作..." << endl;
        sleep(3); // 子进程工作 3 秒
        cout << "子进程：工作完成，即将退出。" << endl;
        exit(0); // 子进程正常退出
    }
    else
    {
        // 父进程代码
        cout << "父进程：成功创建子进程，子进程 PID 为 " << pid << endl;
        cout << "父进程：继续执行，等待子进程状态变化..." << endl;

        // 父进程进入一个循环，模拟执行其他任务
        // 在子进程终止后，父进程会收到 SIGCHLD 信号，并调用信号处理函数
        while (true)
        {
            cout << "父进程：正在做其他事情..." << endl;
            sleep(1); // 父进程暂停 1 秒
        }

        // 程序正常情况下不会到达这里
    }

    return 0;
}
